package com.suse.service.community.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HtmlUtil;
import com.alibaba.fastjson2.JSONObject;
import com.suse.common.base.model.entity.Page;
import com.suse.common.config.response.R;
import com.suse.service.community.constant.TopicConstant;
import com.suse.service.community.constant.UserConstant;
import com.suse.service.community.entity.Message;
import com.suse.service.community.entity.User;
import com.suse.service.community.service.MessageService;
import com.suse.service.community.service.UserService;
import com.suse.service.community.util.UserHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 消息前端控制器
 * </p>
 *
 * @author 辜玉彬
 * @since 2022-09-01 16:10
 */
@Controller
public class MessageController {

    @Resource
    private MessageService messageService;

    @Resource
    private UserService userService;

    @GetMapping("/letter/list")
    public String getLetterList(Model model, Page page) {
        User user = UserHolder.getUser();
        Integer userId = user.getId();
        // 会话分页
        page.setLimit(5);
        page.setPath("/letter/list");
        page.setTotal(messageService.getConversationTotal(userId));
        // 会话列表
        List<Message> conversationList = messageService.getConversationList(userId, page.getOffset(), page.getLimit());
        // 会话VO列表
        List<Map<String,Object>> conversationVoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(conversationList)) {
            for (Message conversation : conversationList) {
                String conversationId = conversation.getConversationId();
                HashMap<String, Object> conversationVo = new HashMap<>();
                conversationVo.put("conversation",conversation);
                conversationVo.put("letterCount",messageService.getLetterTotal(conversationId));
                conversationVo.put("unreadLetterCount",messageService.getConversationUnreadLetterCount(userId,conversationId));
                int targetId = user.getId().equals(conversation.getFromId()) ? conversation.getToId() : conversation.getFromId();
                User target = userService.getUserById(targetId);
                conversationVo.put("target",target);
                conversationVoList.add(conversationVo);
            }
        }
        model.addAttribute("conversationList",conversationVoList);
        // 获取未读私信数
        model.addAttribute("unreadLetterCount",messageService.getUnreadLetterCount());
        // 获取未读通知数
        model.addAttribute("unreadNoticeCount",messageService.getUnreadNoticeCount());
        return "site/letter";
    }

    @GetMapping("/letter/detail/{conversationId}")
    public String getLetterDetail(@PathVariable("conversationId") String conversationId, Page page, Model model) {
        // 私信分页
        page.setLimit(5);
        page.setPath("/letter/detail/" + conversationId);
        page.setTotal(messageService.getLetterTotal(conversationId));
        // 私信列表
        List<Message> letterList = messageService.getLetterList(conversationId, page.getOffset(), page.getLimit());
        // 获取未读私信ID列表
        List<Integer> unreadLetterIdList = getUnreadMessageIdList(letterList);
        // 设置已读
        if (CollectionUtil.isNotEmpty(unreadLetterIdList)) {
            messageService.readLetterList(unreadLetterIdList);
        }
        List<Map<String, Object>> letterVoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(letterList)) {
            for (Message letter : letterList) {
                Map<String, Object> letterVo = new HashMap<>();
                letterVo.put("letter",letter);
                letterVo.put("fromUser",userService.getUserById(letter.getFromId()));
                letterVoList.add(letterVo);
            }
            model.addAttribute("letterList",letterVoList);
            Message letter = letterList.get(0);
            User target = getLetterTarget(letter);
            model.addAttribute("target",target);
        }
        return "site/letter-detail";
    }

    private List<Integer> getUnreadMessageIdList(List<Message> letterList) {
        List<Integer> idList = new ArrayList<>();
        User user = UserHolder.getUser();
        if (CollectionUtil.isNotEmpty(letterList)) {
            for (Message letter : letterList) {
                if (letter.getToId().equals(user.getId()) && letter.getStatus() == 0) {
                    idList.add(letter.getId());
                }
            }
        }
        return idList;
    }

    private User getLetterTarget(Message letter) {
        User user = UserHolder.getUser();
        if (user.getId().equals(letter.getFromId())) {
            return userService.getUserById(letter.getToId());
        }else {
            return userService.getUserById(letter.getFromId());
        }
    }

    @PostMapping("/letter/send")
    @ResponseBody
    public R sendLetter(String toName, String content) {
        User target = userService.getByName(toName);
        if (ObjectUtil.isNull(target)) {
            return R.error("该用户不存在！");
        }
        Message letter = new Message();
        int userId = UserHolder.getUser().getId();
        letter.setFromId(userId);
        letter.setToId(target.getId());
        letter.setContent(content);
        Integer fromId = letter.getFromId();
        Integer toId = letter.getToId();
        if (fromId < toId) {
            letter.setConversationId(fromId + "_" + toId);
        }else {
            letter.setConversationId(toId + "_" + fromId);
        }
        messageService.save(letter);
        return R.success("私信发送成功！");
    }

    @GetMapping("/notice/list")
    public String getNoticeList(Model model) {
        // 获取评论类的最新通知
        Map<String, Object> commentNoticeVo = getTopicNoticeVo(TopicConstant.COMMENT);
        model.addAttribute("commentNotice",commentNoticeVo);
        // 获取点赞类的最新通知
        Map<String, Object> likeNoticeVo = getTopicNoticeVo(TopicConstant.LIKE);
        model.addAttribute("likeNotice",likeNoticeVo);
        // 获取关注类的最新通知
        Map<String, Object> followNoticeVo = getTopicNoticeVo(TopicConstant.FOLLOW);
        model.addAttribute("followNotice",followNoticeVo);
        // 获取未读私信数
        model.addAttribute("unreadLetterCount",messageService.getUnreadLetterCount());
        // 获取未读通知数
        model.addAttribute("unreadNoticeCount",messageService.getUnreadNoticeCount());
        return "site/notice";
    }

    /**
     * 获取主题通知VO
     * @param topic 主题
     * @return 主题通知VO
     */
    private Map<String, Object> getTopicNoticeVo(String topic) {
        Message notice = messageService.getLatestTopicNotice(topic);
        if (ObjectUtil.isNull(notice)) {
            return null;
        }
        // 通知VO
        Map<String, Object> noticeVo = new HashMap<>();
        // 将通知和内容信息放入通知VO中
        putNoticeAndContent(noticeVo,notice);
        int count = messageService.getTopicNoticeCount(topic);
        noticeVo.put("count",count);
        int unreadCount = messageService.getUnreadTopicNoticeCount(topic);
        noticeVo.put("unreadCount",unreadCount);
        return noticeVo;
    }

    /**
     * 将通知和内容信息放入通知VO中
     * @param noticeVo 通知VO
     * @param notice 通知
     */
    private void putNoticeAndContent(Map<String, Object> noticeVo,Message notice) {
        // 通知
        noticeVo.put("notice", notice);
        // 内容
        String content = HtmlUtil.unescape(notice.getContent());
        Map<String, Object> map = JSONObject.parseObject(content, HashMap.class);
        noticeVo.put("user",userService.getUserById((Integer) map.get("userId")));
        noticeVo.put("entityType",map.get("entityType"));
        noticeVo.put("entityId",map.get("entityId"));
        noticeVo.put("postId",map.get("postId"));
    }

    @GetMapping("/notice/detail/{topic}")
    public String getTopicNoticeList(@PathVariable("topic") String topic, Page page,Model model) {
        // 分页信息
        page.setLimit(5);
        page.setPath("/notice/detail/" + topic);
        page.setTotal(messageService.getTopicNoticeCount(topic));
        // 通知列表
        List<Message> noticeList = messageService.getTopicNoticeList(topic, page.getOffset(), page.getLimit());
        List<Map<String, Object>> noticeVoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(noticeList)) {
            for (Message notice : noticeList) {
                // 通知VO
                Map<String, Object> noticeVo = new HashMap<>();
                // 将通知和内容信息放入通知VO中
                putNoticeAndContent(noticeVo,notice);
                noticeVoList.add(noticeVo);
                // 系统用户
                noticeVo.put("systemUser",userService.getUserById(UserConstant.SYSTEM_USER_ID));
            }
        }
        model.addAttribute("noticeList",noticeVoList);
        // 设置通知已读
        List<Integer> unreadNoticeIdList = getUnreadMessageIdList(noticeList);
        messageService.readLetterList(unreadNoticeIdList);
        return "site/notice-detail";
    }

}
